package nvr

import (
	"encoding/xml"
	"gobase/rpcx_work_flow/rpcx_label_center"
	"strings"
)

// sdk接入中心返回json数据格式
type Result struct {
	Code string `json:"code"`
	// Msg  any    `json:"msg"`
	Msg map[string]Msg `json:"msg"`
}

type Msg struct {
	ChannelID   int64  `json:"channelID"`
	DeviceSipID string `json:"deviceSipID"`
	GuardInfo   string `json:"guardInfo"`
	GuardType   int64  `json:"guardType"`
}

// MotionDetection 移动侦测xml
type MotionDetection struct {
	Enabled               bool                  `xml:"enabled"`
	EnableHighlight       bool                  `xml:"enableHighlight"`
	SamplingInterval      int64                 `xml:"samplingInterval"`
	StartTriggerTime      int64                 `xml:"startTriggerTime"`
	EndTriggerTime        int64                 `xml:"endTriggerTime"`
	ReginType             string                `xml:"regionType"`
	Grid                  Grid                  `xml:"Grid"`
	MotionDetectionLayout MotionDetectionLayout `xml:"MotionDetectionLayout"`
}
type Grid struct {
	RowGranularity    int64 `xml:"rowGranularity"`
	ColumnGranularity int64 `xml:"columnGranularity"`
}
type MotionDetectionLayout struct {
	SensitivityLevel int64  `xml:"sensitivityLevel"`
	Layout           Layout `xml:"layout"`
}
type Layout struct {
	GridMap string `xml:"gridMap"`
}

// TamperDetection 视频遮挡xml
type TamperDetection struct {
	Enabled                   bool                      `xml:"enabled"`
	NormalizedScreenSize      NormalizedScreenSize      `xml:"normalizedScreenSize"`
	TampersensitivityLevel    int64                     `xml:"tampersensitivityLevel"`
	TamperDetectionRegionList TamperDetectionRegionList `xml:"TamperDetectionRegionList"`
}
type TamperDetectionRegionList struct {
	TamperDetectionRegion []TamperDetectionRegion `xml:"TamperDetectionRegion"`
}
type TamperDetectionRegion struct {
	Id                    int64                 `xml:"id"`
	Enabled               bool                  `xml:"enabled"`
	SensitivityLevel      int64                 `xml:"sensitivityLevel"`
	RegionCoordinatesList RegionCoordinatesList `xml:"RegionCoordinatesList"`
}

// RegionEntrance 进入区域xml
type RegionEntrance struct {
	Id                       int64                    `xml:"id"`
	Enabled                  bool                     `xml:"enabled"`
	NormalizedScreenSize     NormalizedScreenSize     `xml:"normalizedScreenSize"`
	RegionEntranceRegionList RegionEntranceRegionList `xml:"RegionEntranceRegionList"`
}
type RegionEntranceRegionList struct {
	RegionEntranceRegion []RegionEntranceRegion `xml:"RegionEntranceRegion"`
}
type RegionEntranceRegion struct {
	Id                    int64                 `xml:"id"`
	SensitivityLevel      int64                 `xml:"sensitivityLevel"`
	RegionCoordinatesList RegionCoordinatesList `xml:"RegionCoordinatesList"`
}

// RegionExiting 离开区域xml
type RegionExiting struct {
	Id                      int64                   `xml:"id"`
	Enabled                 bool                    `xml:"enabled"`
	NormalizedScreenSize    NormalizedScreenSize    `xml:"normalizedScreenSize"`
	RegionExitingRegionList RegionExitingRegionList `xml:"RegionExitingRegionList"`
}
type RegionExitingRegionList struct {
	RegionExitingRegion []RegionExitingRegion `xml:"RegionExitingRegion"`
}
type RegionExitingRegion struct {
	Id                    int64                 `xml:"id"`
	SensitivityLevel      int64                 `xml:"sensitivityLevel"`
	RegionCoordinatesList RegionCoordinatesList `xml:"RegionCoordinatesList"`
}

// 以下为通用
type NormalizedScreenSize struct {
	NormalizedScreenWidth  int64 `xml:"normalizedScreenWidth"`
	NormalizedScreenHeight int64 `xml:"normalizedScreenHeight"`
}
type RegionCoordinatesList struct {
	RegionCoordinates []RegionCoordinates `xml:"RegionCoordinates"`
}
type RegionCoordinates struct {
	PositionX int64 `xml:"positionX"`
	PositionY int64 `xml:"positionY"`
}

// GuardType 布防类型
var GuardType = map[int64]string{
	1: "移动侦测",
	2: "遮挡",
	3: "区域进入",
	4: "区域离开",
}

// AlarmReport 报警上报信息
type AlarmReport struct {
	Id        string `gorm:"primary_Key;type:bigint(20) auto_increment;" json:"id"`
	DccID     string `gorm:"column:dcc_id;type:varchar(32);index:idx_dcc_id;comment:接入中心ID" json:"dccId"`
	DeviceID  string `gorm:"column:device_id;type:varchar(32);index:idx_device_id;comment:NVR设备ID" json:"deviceID"`
	ChannelID int64  `gorm:"column:channel_id;type:int(64);index:idx_channel_id;comment:通道ID" json:"channelID"`
	AlarmTime int64  `gorm:"column:alarm_time;type:int(64);index:idx_alarm_time;comment:报警时间" json:"alarmTime"`
	AlarmType int64  `gorm:"column:alarm_type;type:int(64);index:idx_alarm_type;comment:布防类型" json:"alarmType"`
	RegionId  int64  `gorm:"column:region_id;type:int(64);index:idx_region_id;comment:布防区域" json:"regionId"`
}

// XmlStruct 中间数据
type XmlStruct struct {
	MotionDetection MotionDetection
	TamperDetection TamperDetection
	RegionEntrance  RegionEntrance
	RegionExiting   RegionExiting
}

// Xml2Draw Xml转绘制数据
func Xml2Draw(msg map[string]Msg, deviceID string, typeID int64, regionId int64) (*rpcx_label_center.Draw, error) {
	xmlStruct, err := Xml2Struck(msg)
	if err != nil {
		return nil, err
	}
	draw, err := Struck2Draw(*xmlStruct, deviceID, typeID, regionId)
	if err != nil {
		return nil, err
	}
	return &draw, nil
}

// Xml2Struck xml转中间数据
func Xml2Struck(msg map[string]Msg) (*XmlStruct, error) {
	//移动侦测
	var motionDetection MotionDetection
	//遮挡
	var tamperDetection TamperDetection
	//进入
	var regionEntrance RegionEntrance
	//退出
	var regionExiting RegionExiting

	for _, g := range msg {
		switch g.GuardType {
		case 1:
			//移动侦测
			err := xml.Unmarshal([]byte(strings.Replace(g.GuardInfo, "\n", "", -1)), &motionDetection)
			if err != nil {
				return nil, err
			}
		case 2:
			//遮挡
			err := xml.Unmarshal([]byte(strings.Replace(g.GuardInfo, "\n", "", -1)), &tamperDetection)
			if err != nil {
				return nil, err
			}
		case 3:
			//进入
			err := xml.Unmarshal([]byte(strings.Replace(g.GuardInfo, "\n", "", -1)), &regionEntrance)
			if err != nil {
				return nil, err
			}
		case 4:
			//退出
			err := xml.Unmarshal([]byte(strings.Replace(g.GuardInfo, "\n", "", -1)), &regionExiting)
			if err != nil {
				return nil, err
			}
		}
	}

	return &XmlStruct{
		MotionDetection: motionDetection,
		TamperDetection: tamperDetection,
		RegionEntrance:  regionEntrance,
		RegionExiting:   regionExiting,
	}, nil
}

// Struck2Draw 中间数据转绘制
func Struck2Draw(xmlStruct XmlStruct, deviceID string, typeId int64, regionId int64) (rpcx_label_center.Draw, error) {
	var metas []rpcx_label_center.Meta

	//移动侦测
	if typeId == 1 || typeId == 0 {
		if xmlStruct.MotionDetection.MotionDetectionLayout.Layout.GridMap != "" {
			metas = append(metas, rpcx_label_center.Meta{
				X:           0,
				Y:           0,
				StrokeStyle: "rgb(255,0,0)",
				LineWidth:   1,
				Remark:      "移动侦测网格",
				TypeId:      1,
				Grid: &rpcx_label_center.Grid{
					Map:    xmlStruct.MotionDetection.MotionDetectionLayout.Layout.GridMap,
					Column: xmlStruct.MotionDetection.Grid.ColumnGranularity,
					Row:    xmlStruct.MotionDetection.Grid.RowGranularity,
				},
			})
		}
	}

	//遮挡
	if typeId == 2 || typeId == 0 {
		for _, region := range xmlStruct.TamperDetection.TamperDetectionRegionList.TamperDetectionRegion {
			if len(region.RegionCoordinatesList.RegionCoordinates) == 0 {
				continue
			}
			var meta rpcx_label_center.Meta
			var pens []rpcx_label_center.Pen
			for k, p := range region.RegionCoordinatesList.RegionCoordinates {
				if k == 0 {
					continue
				}
				var pen rpcx_label_center.Pen
				pen.X = p.PositionX
				pen.Y = xmlStruct.TamperDetection.NormalizedScreenSize.NormalizedScreenHeight - p.PositionY //以左下角为原点
				pens = append(pens, pen)
			}
			meta.X = region.RegionCoordinatesList.RegionCoordinates[0].PositionX
			meta.Y = xmlStruct.TamperDetection.NormalizedScreenSize.NormalizedScreenHeight - region.RegionCoordinatesList.RegionCoordinates[0].PositionY //以左下角为原点
			meta.StrokeStyle = "rgb(255,0,0)"
			meta.LineWidth = 1
			meta.Fill = true
			meta.FillStyle = "gray"
			meta.Remark = "遮挡"
			meta.TypeId = 2
			meta.ProtoWidth = xmlStruct.TamperDetection.NormalizedScreenSize.NormalizedScreenWidth
			meta.ProtoHeight = xmlStruct.TamperDetection.NormalizedScreenSize.NormalizedScreenHeight
			meta.Pen = &pens
			metas = append(metas, meta)
		}
	}

	//进入
	if typeId == 3 || typeId == 0 {
		for _, region := range xmlStruct.RegionEntrance.RegionEntranceRegionList.RegionEntranceRegion {
			if len(region.RegionCoordinatesList.RegionCoordinates) == 0 {
				continue
			}
			if regionId != 0 && region.Id != regionId {
				continue //按地域过滤
			}
			var meta rpcx_label_center.Meta
			var pens []rpcx_label_center.Pen
			for k, p := range region.RegionCoordinatesList.RegionCoordinates {
				if k == 0 {
					continue
				}
				var pen rpcx_label_center.Pen
				pen.X = p.PositionX
				pen.Y = xmlStruct.RegionEntrance.NormalizedScreenSize.NormalizedScreenHeight - p.PositionY //以左下角为原点
				pens = append(pens, pen)
			}
			meta.X = region.RegionCoordinatesList.RegionCoordinates[0].PositionX
			meta.Y = xmlStruct.RegionEntrance.NormalizedScreenSize.NormalizedScreenHeight - region.RegionCoordinatesList.RegionCoordinates[0].PositionY //以左下角为原点
			meta.StrokeStyle = "yellow"
			meta.Remark = "进入"
			meta.TypeId = 3
			meta.ProtoWidth = xmlStruct.RegionEntrance.NormalizedScreenSize.NormalizedScreenWidth
			meta.ProtoHeight = xmlStruct.RegionEntrance.NormalizedScreenSize.NormalizedScreenHeight
			meta.Pen = &pens
			metas = append(metas, meta)
		}
	}

	//退出
	if typeId == 4 || typeId == 0 {
		for _, region := range xmlStruct.RegionExiting.RegionExitingRegionList.RegionExitingRegion {
			if len(region.RegionCoordinatesList.RegionCoordinates) == 0 {
				continue
			}
			if regionId != 0 && region.Id != regionId {
				continue //按地域过滤
			}
			var meta rpcx_label_center.Meta
			var pens []rpcx_label_center.Pen
			for k, p := range region.RegionCoordinatesList.RegionCoordinates {
				if k == 0 {
					continue
				}
				var pen rpcx_label_center.Pen
				pen.X = p.PositionX
				pen.Y = xmlStruct.RegionExiting.NormalizedScreenSize.NormalizedScreenHeight - p.PositionY //以左下角为原点
				pens = append(pens, pen)
			}
			meta.X = region.RegionCoordinatesList.RegionCoordinates[0].PositionX
			meta.Y = xmlStruct.RegionExiting.NormalizedScreenSize.NormalizedScreenHeight - region.RegionCoordinatesList.RegionCoordinates[0].PositionY //以左下角为原点
			meta.StrokeStyle = "yellow"
			meta.Remark = "退出"
			meta.TypeId = 4
			meta.ProtoWidth = xmlStruct.RegionExiting.NormalizedScreenSize.NormalizedScreenWidth
			meta.ProtoHeight = xmlStruct.RegionExiting.NormalizedScreenSize.NormalizedScreenHeight
			meta.Pen = &pens
			metas = append(metas, meta)
		}
	}

	var frame rpcx_label_center.Frame
	frame.Metas = &metas

	var frames []rpcx_label_center.Frame
	frames = append(frames, frame)

	var draw rpcx_label_center.Draw
	draw.DeviceId = deviceID
	draw.Frames = &frames

	return draw, nil
}
